/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.Text;
using MyPhotoIndex.Interfaces.Imaging;
using MyPhotoIndex.Interfaces;
using MyPhotoIndex.Plugins.DataProviders;
using System.Data;
using System.Xml.Serialization;
using MyPhotoIndex.Utilities;
using System.IO;

namespace MyPhotoIndex.ImageBank
{
    [Serializable]
    public class ImageCategoryCollection : Singleton<ImageCategoryCollection>, IImageCategoryCollection
    {
        private IImageCategoriesDataAccessProvider m_dataAccessProvider;
        private List<IImageCategory> m_list = new List<IImageCategory>();
        private Dictionary<int, IImageCategory> m_map = new Dictionary<int, IImageCategory>();

        #region IImageCategoryCollection Members

        public event EventHandler<EventArgs> ImageCategoryCollectionLoadedEvent;

        public IImageCategory this[int id]
        {
            get { return m_list[id]; }
        }

        public IImageCategory GetById(int id)
        {
            IImageCategory category = null;
            if (m_map.TryGetValue(id, out category) == false)
            {
                return null;
            }

            return category;
        }

        public int Count
        {
            get { return m_list.Count; }
        }

        public void Save(IImageCategory category)
        {
            category.Description = category.Description.Trim();
            DataTable categoryDataTable = m_dataAccessProvider.GetImageCategories();
            DataRow dataRow = null;

            dataRow = categoryDataTable.Rows.Find(new object[] { category.Id });
            if (dataRow == null)
            {
                dataRow = categoryDataTable.Rows.Add(new Object[] { category.Id, category.Description, category.ColorIndex });
            }
            else
            {
                dataRow[(int)ImageCategoriesDataSourceColumnId.Description] = category.Description;
                dataRow[(int)ImageCategoriesDataSourceColumnId.ColorIndex] = category.ColorIndex;
            }

            m_dataAccessProvider.UpdateDataTable(categoryDataTable, false, false);
            categoryDataTable.AcceptChanges();
        }

        #endregion

        #region IEnumerable<IImageData> Members

        public IEnumerator<IImageCategory> GetEnumerator()
        {
            return m_list.GetEnumerator();
            
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public void Add(object category)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        public void Load(IImageCategoriesDataAccessProvider dataAccessProvider)
        {
            m_dataAccessProvider = dataAccessProvider;

            m_list.Clear();
            m_map.Clear();

            try
            {
                DataTable dataTable = m_dataAccessProvider.GetImageCategories();
                if (dataTable.Rows.Count == 0)
                {
                    LoadDefaultCategories();
                    dataTable = m_dataAccessProvider.GetImageCategories();
                }

                foreach (DataRow row in dataTable.Rows)
                {
                    ImageCategory imageCategory = new ImageCategory();

                    if (row.IsNull((int)ImageCategoriesDataSourceColumnId.Id) == false)
                    {
                        imageCategory.Id = Convert.ToInt32(row[(int)ImageCategoriesDataSourceColumnId.Id]);
                    }

                    if (row.IsNull((int)ImageCategoriesDataSourceColumnId.Description) == false)
                    {
                        imageCategory.Description = Convert.ToString(row[(int)ImageCategoriesDataSourceColumnId.Description]);
                    }

                    if (row.IsNull((int)ImageCategoriesDataSourceColumnId.ColorIndex) == false)
                    {
                        imageCategory.ColorIndex = Convert.ToInt32(row[(int)ImageCategoriesDataSourceColumnId.ColorIndex]);
                    }

                    m_list.Add(imageCategory);
                    m_map.Add(imageCategory.Id, imageCategory);
                }

                if (ImageCategoryCollectionLoadedEvent != null)
                {
                    ImageCategoryCollectionLoadedEvent.Invoke(this, EventArgs.Empty);
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }

        private void LoadDefaultCategories()
        {
            try
            {
                List<ImageCategory> list = new List<ImageCategory>();

                string source = Path.Combine(ApplicationFolders.ApplicationFolder, @"Data\en-us\ImageCategories.xml");
                XmlSerializer serializer = new XmlSerializer(list.GetType());

                using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read))
                {
                    list = (List<ImageCategory>)serializer.Deserialize(fs);
                }

                foreach (IImageCategory imageCat in list)
                {
                    Save(imageCat);
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }
    }
}
